#pragma once


#include <iostream>
#include <string>
#include <memory>
#include <cstring>
#include <jsoncpp/json/json.h>

const static std::string sep = "\r\n";


// 像下面这样，规定结构化的数据就是在规定协议啊 

// 设计一下协议的报头和报文的完整格式，这是为了读取完整的请求，而不是半个之类的
// "len"\r\n"{json}"\r\n  --> 完整的报文格式
// len 表示有效载荷（json 串）的长度！
// len 必须是连续的，由于没有特殊字符，再读取到 \r\n 后就可以提取 len 转变为整型
// 此后再继续读取 len 长度的 json 串就一定是完整合法的
// \r\n 主要是为了区分 len 和 json 串，但其他字符也是可以用来区分的，其他在暂时没什么用，也是为了打印方便（debug）

// 其实 \r\n 就已经能够在宏观上，区分每一个 json 串
// 但实际上 json 串中也可能含有 \r\n 
// 所以 len 的添加是必要的

std::string Encode(const std::string& jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

// 如果没读到完整的，那就直接不用做，继续读啊，读到完整的请求才能做处理啊！ 
// 而一次只识别一份 "len"\r\n"{json}"\r\n 这样的报文
// 剩下的下次再说
std::string Decode(std::string& packagestream)
{
    // 分析
    auto pos = packagestream.find(sep);
    if (pos == std::string::npos) return std::string();
    std::string lenstr = packagestream.substr(0, pos);
    size_t len = std::stoi(lenstr);
    // 计算一个完整报文的长度 
    size_t total = lenstr.size() + len + sep.size() * 2;
    if (packagestream.size() < total) return std::string();

    // 提取
    std::string jsonstr = packagestream.substr(pos + sep.size(), len);
    packagestream.erase(0, total);

    return jsonstr;
}



// Request req = {10, 20, '+'}; 
class Request
{
public:
    Request()
    {}

    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {}

    // 序列化
    bool Serialize(std::string* out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        // Json::StyledWriter writer;
        Json::FastWriter writer;
        std::string result = writer.write(root);

        *out = result;
        return true;
    }

    // 反序列化
    bool Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader reader;
        bool result = reader.parse(in, root);

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return result;
    }

    int GetX()
    {
        return _x;
    }

    int GetY()
    {
        return _y;
    }

    char GetOper()
    {
        return _oper;
    }

    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }

    ~Request()
    {}

private:
    int _x;
    int _y;
    char _oper;
};


// Response resp = {30, 0}; 
class Response
{
public:
    Response()
        : _result(0), _code(0), _desc(strerror(0))
    {}

    // 序列化
    bool Serialize(std::string* out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        Json::FastWriter writer;
        std::string result = writer.write(root);

        *out = result;
        return true;
    }

    // 反序列化
    bool Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader reader;
        bool result = reader.parse(in, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return result;
    }

    void SetResult(int result)
    {
        _result = result;
    }

    void SetCode(int code)
    {
         _code = code;
    }

    void SetDesc(const std::string& desc)
    {
        _desc = desc;
    }

    void Print()
    {
        std::cout << "result: " << _result << ", code: " << _code << ", desc: " << _desc << std::endl;
    }

    ~Response()
    {}
    
private:
    int _result;
    int _code;          // 退出状态码，结果是否可信以及相关原因 ->  0: success, 1: div zero, 2: 非法操作 
    std::string _desc;  // 退出状态码的描述 
};


// 工厂模式
class Factory
{
private:
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }

    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }

private:
};


